Skip to content

HDT3213/godis

Repository files navigation

Godis

license Build Status Coverage Status Go Report Card Go Reference
Mentioned in Awesome Go

中文版

Godis is a golang implementation of Redis Server, which intents to provide an example of writing a high concurrent middleware using golang.

Key Features:

  • Support string, list, hash, set, sorted set, bitmap
  • Concurrent Core for better performance
  • TTL
  • Publish/Subscribe
  • GEO
  • AOF and AOF Rewrite
  • RDB read and write
  • Multi Database and SELECT command
  • Transaction is Atomic and Isolated. If any errors are encountered during execution, godis will rollback the executed commands
  • Replication
  • Server-side Cluster which is transparent to client. You can connect to any node in the cluster to access all data in the cluster.
    • Cluster metadata management based on Raft. Support dynamic expansion, rebalancing and failover.
    • MSET, MSETNX, DEL, Rename, RenameNX command is supported and atomically executed in cluster mode, allow over multi node.
    • MULTI Commands Transaction is supported within slot in cluster mode

If you could read Chinese, you can find more details in My Blog.

Get Started

You can get runnable program in the releases of this repository, which supports Linux and Darwin system.

./godis-darwin
./godis-linux

You could use redis-cli or other redis client to connect godis server, which listens on 0.0.0.0:6399 on default mode.

The program will try to read config file path from environment variable CONFIG.

If environment variable is not set, then the program try to read redis.conf in the working directory.

Please see example.conf for all configuration information.

cluster mode

We provide node1.conf and node2.conf for demonstration. use following command line to start a two-node-cluster:

CONFIG=node1.conf ./godis-darwin &
CONFIG=node2.conf ./godis-darwin &

Connect to a node in the cluster to access all data in the cluster:

redis-cli -p 6399

Please refer to example.conf for cluster configuration.

Supported Commands

See: commands.md

Benchmark

Environment:

Go version:1.23 System: MacOS Monterey 12.5 M2 Air

Performance report by redis-benchmark:

PING_INLINE: 179211.45 requests per second, p50=1.031 msec                    
PING_MBULK: 173611.12 requests per second, p50=1.071 msec                    
SET: 158478.61 requests per second, p50=1.535 msec                    
GET: 156985.86 requests per second, p50=1.127 msec                    
INCR: 164473.69 requests per second, p50=1.063 msec                    
LPUSH: 151285.92 requests per second, p50=1.079 msec                    
RPUSH: 176678.45 requests per second, p50=1.023 msec                    
LPOP: 177619.89 requests per second, p50=1.039 msec                    
RPOP: 172413.80 requests per second, p50=1.039 msec                    
SADD: 159489.64 requests per second, p50=1.047 msec                    
HSET: 175131.36 requests per second, p50=1.031 msec                    
SPOP: 170648.45 requests per second, p50=1.031 msec                    
ZADD: 165289.25 requests per second, p50=1.039 msec                    
ZPOPMIN: 185528.77 requests per second, p50=0.999 msec                    
LPUSH (needed to benchmark LRANGE): 172117.05 requests per second, p50=1.055 msec                    
LRANGE_100 (first 100 elements): 46511.62 requests per second, p50=4.063 msec                   
LRANGE_300 (first 300 elements): 21217.91 requests per second, p50=9.311 msec                     
LRANGE_500 (first 500 elements): 13331.56 requests per second, p50=14.407 msec                    
LRANGE_600 (first 600 elements): 11153.25 requests per second, p50=17.007 msec                    
MSET (10 keys): 88417.33 requests per second, p50=3.687 msec  

Read My Code

If you want to read my code in this repository, here is a simple guidance.

  • project root: only the entry point
  • config: config parser
  • interface: some interface definitions
  • lib: some utils, such as logger, sync utils and wildcard

I suggest focusing on the following directories:

  • tcp: the tcp server
  • redis: the redis protocol parser
  • datastruct: the implements of data structures
    • dict: a concurrent hash map
    • list: a linked list
    • lock: it is used to lock keys to ensure thread safety
    • set: a hash set based on map
    • sortedset: a sorted set implements based on skiplist
  • database: the core of storage engine
    • server.go: a standalone redis server, with multiple database
    • database.go: data structure and base functions of single database
    • exec.go: the gateway of database
    • router.go: the command table
    • keys.go: handlers for keys commands
    • string.go: handlers for string commands
    • list.go: handlers for list commands
    • hash.go: handlers for hash commands
    • set.go: handlers for set commands
    • sortedset.go: handlers for sorted set commands
    • pubsub.go: implements of publish / subscribe
    • aof.go: implements of AOF persistence and rewrite
    • geo.go: implements of geography features
    • sys.go: authentication and other system function
    • transaction.go: local transaction
  • cluster:
    • cluster.go: entrance of cluster mode
    • com.go: communication within nodes
    • del.go: atomic implementation of delete command in cluster
    • keys.go: keys command
    • mset.go: atomic implementation of mset command in cluster
    • multi.go: entrance of distributed transaction
    • pubsub.go: pub/sub in cluster
    • rename.go: rename command in cluster
    • tcc.go: try-commit-catch distributed transaction implementation
  • aof: AOF persistence

License

This project is licensed under the GPL license.

About

A Golang implemented Redis Server and Cluster. Go 语言实现的 Redis 服务器和分布式集群

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Contributors 33